package org.liveboardgames.agricola.vo.farm
{
	import com.adobe.cairngorm.vo.IValueObject;
	
	import flash.utils.IDataInput;
	import flash.utils.IDataOutput;
	import flash.utils.IExternalizable;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ListCollectionView;
	
	import org.liveboardgames.agricola.vo.card.Card;
	import org.liveboardgames.agricola.vo.common.IResourceContainer;
	import org.liveboardgames.common.dictionary.collections.HashCollection;
	import org.liveboardgames.common.dictionary.collections.IMap;

	[RemoteClass(alias="org.liveboardgames.agricola.domain.farm.Farm")]
	[Bindable]
	public class Farm implements IValueObject, IResourceContainer, IExternalizable
	{
		public var id:int;

		/**
		 * Represents the resources possessed by the player,
		 * i.e. the resources present in the farm. This could
		 * have been stored in the Player class instead of the
		 * Farm though.
		 */
		public var resources:HashCollection;

		/** The list of all the farm's tiles. */
		public var tiles:ListCollectionView;

		/**
		 * The list of all the cards played by the owner of the farm.
		 * This is really a List<Card>.
		 */
		public var playedCards:ListCollectionView;

		public function setTileAt(tile:FarmTile, tileID:int):void
		{
			if (tiles == null)
			{
				tiles = new ArrayCollection();
			}
			this.tiles.addItemAt(tile, tileID);
		}

		public function getTileAt(tileID:int):FarmTile
		{
			var tile:FarmTile = null;
			if (tiles != null && tiles.length > tileID)
			{
				tile = this.tiles.getItemAt(tileID) as FarmTile;
			}
			return tile;
		}

		public function addResource(resource:String, quantity:int):void
		{
			if (this.resources == null)
			{
				resources = new HashCollection();
			}
			var currentQuantity:int = this.resources.getValue(resource) as int;
			this.resources.put(resource, Math.max(0, currentQuantity + quantity));
		}

		public function addResources(newResources:IMap):void
		{
			if (newResources != null)
			{
				for each (var resource:String in newResources.getKeys())
				{
					addResource(resource, newResources.getValue(resource) as int);
				}
			}
		}

		public function removeResources(resources:IMap):void
		{
			if (this.resources != null && resources != null)
			{
				for each (var resourceType:String in resources.getKeys())
				{
					var quantity:int = resources.getValue(resourceType);
					addResource(resourceType, -quantity);
				}
			}
		}

		public function addPlayedCard(card:Card):void
		{
			if (this.playedCards == null)
			{
				this.playedCards = new ArrayCollection();
			}
			this.playedCards.addItem(card);
		}
		
		public function removePlayedCardById(cardId:int):void
		{
			if (this.playedCards != null)
			{
				var index:int;
				for each (var card:Card in this.playedCards)
				{
					if (card.cardId == cardId)
					{
						index = this.playedCards.getItemIndex(card);
					}
				}
				this.playedCards.removeItemAt(index);
			}
		}

		public function readExternal(input:IDataInput):void
		{
			trace("read external in Farm");
			super.readExternal(input);
		}

		public function writeExternal(output:IDataOutput):void
		{
			trace("write external in Farm");
			super.writeExternal(output);
		}
	}
}